package org.lisen.mvc.framework;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;


/**
 * 中央控制器，负责接收所有的请求并分别给控制器具体处理
 * @author Administrator
 */
@WebServlet("*.action")
public class ActionDispatchServlet extends HttpServlet {
	
	//用于保存path与action子控制器的映射
	//public static Map<String, Action> actionMap = new HashMap<>();
	
	private static ConfigModel configModel;
	
	static {
		//actionMap.put("/students", new StudentAction());
		//actionMap.put("/books", new BookAction());
		configModel  = ConfigModelFactory.getConfigModel();
	}
	
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws IOException, ServletException {
		doPost(request, response);
	}
	
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws IOException, ServletException {
		
		/*
		 * 	getServletPath():获取能够与“url-pattern”中匹配的路径，注意是完全匹配的部分，*的部分不包括。
		 *	getPathInfo():与getServletPath()获取的路径互补，能够得到的是“url-pattern”中*d的路径部分
		 *	getContextPath():获取项目的根路径
		 *	getRequestURI:获取根路径到地址结尾
		 *	getRequestURL:获取请求的地址链接（浏览器中输入的地址）
		 *	getServletContext().getRealPath("/"):获取“/”在机器中的实际地址
		 *	getScheme():获取的是使用的协议(http 或https)
		 *	getProtocol():获取的是协议的名称(HTTP/1.11)
		 *	getServerName():获取的是域名(xxx.com)
		 *	getLocalName:获取到的是IP
		 */
		String servletPath = request.getServletPath();
		String path = servletPath.split("\\.")[0];
		
		Action action = getActionByPath(path);
		
		//处理请求参数
		if(action instanceof ModelDrive) {
			Object model = ((ModelDrive) action).getModel();
			if(model != null) {
				try {
					BeanUtils.populate(model, request.getParameterMap());
				} catch (Exception e) {
					throw new RuntimeException("在中央处理器中处理请求参数时发生异常", e);
				}
			}
		}
		
		String name = action.exeute(request, response);
		
		if(name == null) return;
		
		ForwardModel forwardModel = getForwardModel(path, name);
		if (forwardModel.isRedirect()) {
			response.sendRedirect(request.getContextPath() + "/" + forwardModel.getPath());
		} else {
			request.getRequestDispatcher(forwardModel.getPath()).forward(request, response);
		}
	}
	
	
	//通过请求路径获取对应的action实例
	private Action getActionByPath(final String path) {
		ActionModel action = configModel.find(path);
		try {
			Class<?> clazz = Class.forName(action.getType());
			return (Action)clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException("创建Action实例异常"+e.getMessage(), e);
		}
	}
	
	public ForwardModel getForwardModel(String path, String name) {
		return configModel.find(path).find(name);
	}

}
